# -*- coding: utf-8 -*-

import os
import ast


ALIAS_TYPES = {
    'IntEnum': 'Enum'
}


def convert_to_ast(filepath: str):
    # Check file existence.
    if not os.path.isfile(filepath):
        raise Exception('Failed to load Python file: {}'.format(filepath))
    # Read the file content.
    with open(filepath, 'r') as node_file:
        node_data = node_file.read()
    return ast.parse(node_data)


def split_file_ast(ast_file: ast.Module):
    # Parse the file ast.
    file_ast = {'import': [],
                'Pack': [],
                'Enum': [],
                'Lane': [],
                'Channel': [],
                'Node': []}
    # Loop and check in the data.
    for ast_line in ast_file.body:
        # Process the definition.
        if isinstance(ast_line, ast.Import) or \
                isinstance(ast_line, ast.ImportFrom):
            file_ast['import'].append(ast_line)
        elif isinstance(ast_line, ast.ClassDef):
            # It could be Lane, Channel or Node, check the base.
            base_class = ast_line.bases
            if len(base_class) != 1 or not isinstance(base_class[0], ast.Name):
                raise Exception('All the class definition should be '
                                'based on Enum, Pack, Lane, Channel or Node.')
            # Check the name of the base class.
            base_class = base_class[0].id
            if base_class not in file_ast:
                # Check whether it occurs in alias list.
                if base_class in ALIAS_TYPES:
                    file_ast[ALIAS_TYPES[base_class]].append(ast_line)
                else:
                    raise Exception('Class {} is not a subclass of Enum, Pack, Lane, Channel or Node.'.format(ast_line.name))
            else:
                # Add the class into node.
                file_ast[base_class].append(ast_line)
    # Give back the ast.
    return file_ast
